package com.baihejia.common.dubbo.server;

import com.baihejia.common.dubbo.domain.Subway;
import com.baihejia.common.dubbo.domain.SubwayQuery;

import java.util.Map;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

public class SubwayClient extends Es<Subway, SubwayQuery> {

    public SubwayClient() {
        super("subway-index", "subway");
    }

	@Override
	protected XContentBuilder buildMapping() throws Exception {
		return XContentFactory.jsonBuilder().prettyPrint()
				.startObject()
                .startObject("subway")
                .startObject("properties")
                .startObject("coordinates")
                .field("type", "geo_point")
                .endObject()
                .startObject("cityId")
                .field("type", "long")
                .endObject()
                .endObject()
                .endObject()
                .endObject();
	}

	@Override
	protected void rebuildIndex(String index) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected void putExtraFields(Map<String, Object> jsonObject, Subway entity) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected SearchHits esHits(SubwayQuery query) throws Exception {
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if (query.cityId > 0) {
            boolQueryBuilder.must(QueryBuilders.termQuery("cityId", query.cityId));
        }

        GeoPoint point = new GeoPoint(query.lat, query.lon);

        GeoDistanceQueryBuilder geoDistanceQueryBuilder = QueryBuilders.geoDistanceQuery("coordinates")
                .point(point)
                .distance(1.2, DISTANCE_UNIT)
                .geoDistance(GeoDistance.ARC);

        boolQueryBuilder.must(geoDistanceQueryBuilder);

        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(getIndexAlias()).setTypes(getType())
                .setQuery(boolQueryBuilder)
                .setFrom(0)
                .setSize(100);

        searchRequestBuilder.addSort(SortBuilders.geoDistanceSort("coordinates", point)
                .order(SortOrder.ASC)
                .points(point)
                .unit(DISTANCE_UNIT));

        SearchResponse resp = searchRequestBuilder.execute().actionGet();
        return resp.getHits();
	}


}
